package uk.ac.lkl.lpp;



import java.io.File;
import java.util.logging.Logger;
import java.net.URI;

import javax.swing.event.ChangeListener;

import uk.ac.lkl.common.util.ChangeSupport;

import uk.ac.lkl.lpp.model.PedagogyPlanModel;
import uk.ac.lkl.lpp.ui.PedagogyPlanUI;
import uk.ac.lkl.lpp.xml.XMLException;
import uk.ac.lkl.lpp.xml.XMLPedagogyPlanProcessor;


/**
 * 
 * 
 * <p>
 * Question: add convinience constructor with URI param?
 * </p>
 * <p>
 * Answer: Yep
 * </p>
 * 
 * <p>
 * Question: add dirty flag for saving?
 * </p>
 * 
 * <p>
 * Answer: yep. Should be able to do this through listening to all relevant data
 * structures with a single change listener and setting a boolean as appropriate
 * in this class to represent the dirty flag.
 * </p>
 * 
 * @author Darren Pearce
 * @version $Revision$
 * @version $Date$
 * 
 */
public class PedagogyPlan {
	private static final Logger logger = Logger.getLogger("uk.ac.lkl.lpp");

    private ChangeSupport changeSupport;

    private PedagogyPlanModel model;

    private PedagogyPlanUI ui;

    private PedagogyPlanProcessor processor;


    /**
     * <p>
     * Question: if processor is singleton - fine. else, delay evaluation?
     * </p>
     * 
     */
    public PedagogyPlan() {
        changeSupport = new ChangeSupport(this);
        // for now, this is hard-wired and immutable
        processor = new XMLPedagogyPlanProcessor();
        model = new PedagogyPlanModel();
        ui = new PedagogyPlanUI(this);
    }


    public PedagogyPlanModel getModel() {
        return model;
    }


    // todo: clean this up -- mustn't call change listeners
    public void setUI(PedagogyPlanUI ui) {
        this.ui = ui;
    }


    public PedagogyPlanUI getUI() {
        return ui;
    }


    public void writeToFile(File file) {
        processor.writeToFile(this, file);
        setClean();
    }


    public void readFromURI(URI uri) throws XMLException {
        processor.readFromURI(this, uri);
        setClean();
    }


    /**
     * Todo: prevent changes being signalled when read in.
     * 
     * @param file
     * 
     */
    public void readFromFile(File file) throws XMLException {
        processor.readFromFile(this, file);
        setClean();
    }


    public void setModel(PedagogyPlanModel model) {
        if (model == this.model)
            return;

        this.model = model;
        fireStateChanged();
    }

    /**
     *	This will set the dirtyFlag to true indicating that something was changed since 
     *	last save, or set to false when saved
     * 
     */
    public void setDirty(){
    	model.setDirty(true);
    	// URI: logger example
    	logger.fine("Set dirty");
    }
    public void setClean(){
    	model.setDirty(false);
    	// URI: logger example
    	logger.fine("Set Clean");
    }
    public boolean getDirtyFlag(){
    	return model.getDirty();
    }
    /**
     * Convenience method for when want to set both model and UI.
     * 
     * This does not fire any state changed since the ui will be plugged in to
     * the new model.
     * 
     * todo: provide install/uninstall in ui so can remove listeners. Otherwise
     * these are left hanging.
     * 
     * @param model
     * @param ui
     * 
     */
    public void setModelAndView(PedagogyPlanModel model, PedagogyPlanUI ui) {
        this.model = model;
        this.ui = ui;
    }


    public void addChangeListener(ChangeListener listener) {
        changeSupport.addListener(listener);
        
    }


    public void removeChangeListener(ChangeListener listener) {
        changeSupport.removeListener(listener);
    }


    private void fireStateChanged() {
        changeSupport.fireStateChanged();
        
    }
    
}
